﻿///////////////////////////////////////////////////////////////////////////////
//
//  Elfin
//  Kolonitsky Developers Alliance (c) 2012
//  All rights received
//
///////////////////////////////////////////////////////////////////////////////

package org.kolonitsky.alexey.banner 
{

    import org.kolonitsky.alexey.debug.DebugWrapper;
    
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.net.URLRequest;
    import flash.net.navigateToURL;
    

    /**
     * Base class for all banners. Main purpose for <code>TUTBanner</code> class --- 
     * create bannerClick button, detect additional information about banner from file 
     * name, and get target link from flash vars. In addion hide default Flash Player 
     * menu.
     * 
     * @date 11.05.2009
     * @update 3.11.2009
     * @author Alexey Kolonitsky
     * @version 0.0.3
     */
    dynamic public class Banner extends MovieClip 
    {
        /**
         * Default banner url. Used if not specified bannerLink parameter by any other ways
         */
        private static const DEFAULT_URL:String = "http://kolonitsky.org/";
                
        /**
         * Planed banner width.
         * Used when resize banner for positioned react area
         */
        public var bannerWidth:Number = 0.0;
        
        /**
         * Planed banner height
         */
        public var bannerHeight:Number = 0.0;

        /** 
         * Banner button. If banner batton not defined on timeline
         * them drawed, and placed on child's chain top.
         */
        public var bannerButton:MovieClip;

        /**
         * Banner Management System Identifier 
         */
        public var bannerId:uint = 0;

        /**
         * Banner target url. Used as distenation page wich open in browser
         * after click on bannerButton.
         */
        public var bannerLink:String;


        /**
         * Constructor 
         */
        public function Banner () 
        {
            super();
            DebugWrapper.log("Banner Created.");
            
            parsFileName()
            getExternalParameters()
            
            addEventListener(Event.ENTER_FRAME, enterFrameHandler)

            // init stage for not ebeded banners.
            try 
            {
                stage.align = "T";
                stage.scaleMode = "showAll";
				bannerWidth = stage.stageWidth;
				bannerHeight = stage.stageHeight;
                stage.addEventListener(Event.RESIZE, resizeHandler);
            } 
            catch (error:SecurityError)
            {
                DebugWrapper.log("ERROR: " + error.message)
            } 
            catch (error:Error) 
            {
                DebugWrapper.log("ERROR: " + error.message)
            }
        }
        
        
        
        
        //---------------------------------------------------------------------
        //
        //  Private
        //
        //---------------------------------------------------------------------
        
        /**
         *  This flag indicate debug mode. In debug mode banner button displayed.
         *  this property used only in debug flash player. Value for this flag 
         *  read from flashvars.
         */
        private var isDebug:Boolean = false;

        /**
         *  Create clickable area for banner if it not created manualy.
         *  Stage get banner button and try initialize it. If button not found
         *  it created.
         */
        private function updateBannerButton():void
        {
            // Button created or defined on timeline
            if (bannerButton)
            {
                DebugWrapper.log("INFO: bannerButton is exists");
                bannerButton.useHandCursor = true;
                bannerButton.buttonMode = true;
            }
            
            // Button not defined on timeline
            else
            {
				var line2:String = bannerWidth && bannerHeight ? "Size " + bannerWidth + "x" + bannerHeight : "";
                DebugWrapper.log("INFO: Update bannerButton, Stage align: " + stage.align + " " + line2);
				
                var xPos: Number = stage.align.indexOf("L") < 0 ? bannerWidth / 2 : 0; 
                var yPos: Number = stage.align.indexOf("T") < 0 ? bannerHeight / 2 : 0;
                if (bannerButton) 
                {
                    removeChild(bannerButton);
                    bannerButton = null
                }
                bannerButton = new MovieClip();
                bannerButton.useHandCursor = true;
                bannerButton.buttonMode = true;
                
                if (isNaN(bannerWidth) || isNaN(bannerHeight) 
					|| bannerWidth == 0 || bannerHeight == 0)
                {
                    DebugWrapper.log("WARNING: Banner size not specified. Drow standard bannerButton size 100x100.");
                    bannerWidth = bannerWidth || 100;
                    bannerHeight = bannerHeight || 100;
                }
                
                bannerButton.graphics.beginFill(0x00FF00, isDebug ? 0.3 : 0.0);
                bannerButton.graphics.drawRect(-xPos, -yPos, bannerWidth, bannerHeight);
                bannerButton.graphics.endFill();
                
                // Draw center point for clip.
                if (isDebug) 
                {
                    bannerButton.graphics.beginFill(0xFF0000, 1);
                    bannerButton.graphics.drawCircle(0, 0, 1);
                    bannerButton.graphics.endFill();
                }
                
                bannerButton.x = xPos;
                bannerButton.y = yPos;
                addChild(bannerButton);

            }
            
            if (!bannerButton.hasEventListener(MouseEvent.MOUSE_UP))
                bannerButton.addEventListener(MouseEvent.MOUSE_UP, onBannerClick);
        }


        /** 
         *  Get external parameters form flashvars. Used with banner system
         *  for pass trackable links.
         */
        private function getExternalParameters (): void 
        {
            var param: Object = root.loaderInfo.parameters;
            if (param)
            {
                bannerLink = param.link || param.link1 || param.clickTAG || DEFAULT_URL;
                bannerId = param.bannerId;
                isDebug = String(param.debug) == "true";
            }
            else
            {
                DebugWrapper.log("INFO: Flash vars is empty");
            }
        }

        /**
         *  Pars file name, detect information about typical banner properties
         *  Detected file name like <id>_category<width>x<height>-<version>
         */
        private function parsFileName (): void
        {
            var fileName:String = loaderInfo.url
            var namePattern:RegExp = /[\d\w%]*\.swf/i;
            var idPattern:RegExp = /^\d{1,4}/i;
            var sizePattern:RegExp = /(\d{1,4})x(\d{1,4})/i;
            
            var swfName:String = namePattern.exec(fileName);
            if (swfName == null)
            {
                DebugWrapper.log("INFO: File name in not correct. Right file name must contin only digits and word characters.");
                return;
            }
            
            var arId:String = idPattern.exec(swfName);
            if (arId == "") 
            {
                DebugWrapper.log("INFO: File name not contain addition information");
                return;
            }
            
            bannerId = uint(arId);
            
            var arSize:Array = swfName.match(sizePattern);
            if (arSize && arSize.length)
            {
                bannerWidth = arSize[1];
                bannerHeight = arSize[2];
                
                var ind:int = String(arSize[0]).indexOf(arId);
                bannerId = ind == -1 ? bannerId : 0;
            }
            
			var line1:String = "Banner " + decodeURI(swfName);
            var line2:String = bannerWidth && bannerHeight ? "Size " + bannerWidth + "x" + bannerHeight : "";
            var line3:String = bannerId ? "Id " + bannerId : "";
            DebugWrapper.log("INFO: " + [line1, line2, line3].join(", "));
        }
        
        
        //---------------------------------------------------------------------
        // Event handlers
        //---------------------------------------------------------------------
        
        /** 
         * Start init banner 
         */
        private function enterFrameHandler(event:Event): void 
        {
            removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
            resizeHandler();
            updateBannerButton();
        }
        
        /** 
         * Resize banner react area when resize banner 
         */
        private function resizeHandler (event:Event=null): void 
        {
            try 
            {
                if (stage.scaleMode == "noScale") 
                {
                    bannerWidth = stage.stageWidth;
                    bannerHeight = stage.stageHeight;
                    DebugWrapper.log("INFO: Banner size has been updated. ");
                }
            } 
            catch (error:Error) 
            {
                DebugWrapper.log("ERROR: " + error.message);
            }
        }

        /** 
         * Open link in new window
         */
        private function onBannerClick (event:MouseEvent): void 
        {
            DebugWrapper.log("onBannerClick() gotoURL: " + bannerLink);
            navigateToURL(new URLRequest(bannerLink), "_blank");
        }
    }

}